
import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Description: TODO
 * @author: colagy
 * @date: 2020-12-08 6:57 PM
 */
public class FormatUtil {

    private static Pattern linePattern = Pattern.compile("-(\\w)");

    /**
     * 下划线转驼峰,正常输出
     *
     * @param str
     * @return
     */
    public static String lineToHump(String str) {
        Matcher matcher = linePattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    public static void main(String[] args) throws IOException {

        // 获取文件路径
        String url = FormatUtil.class.getResource("screen.vue").getPath();
        System.out.println(url);
        FileReader fileReader = null;
        BufferedReader bufferedReader = null;

        // 结果文本
        StringBuilder resultText = new StringBuilder();
        try {
            fileReader = new FileReader(url);
            // 读取文件
            bufferedReader = new BufferedReader(fileReader);

            // 行链表 用于查找 class样式名称
            LinkedList<String> lineList = new LinkedList<>();
            // class样式映射
            Map<String, Map<String, String>> classMap = new HashMap<>();

            // 遍历行 查询style class
            for (String line; (line = bufferedReader.readLine()) != null; ) {
                // 每行插入链表头
                lineList.addFirst(line);
                // class样式 识别正则
                Matcher classMatcher = Pattern.compile(".*?-?.*?:.*?px.*?;").matcher(line);
                // id class 绑定样式 识别正则
                Matcher classUseMatcher = Pattern.compile("(class|id)=\"([0-9a-z-])*?\"").matcher(line);
                if (line.contains("style=\"")) { // 处理style
                    // 行文本头部加入结果文本
                    resultText.append(line, 0, line.indexOf("style=\""));
                    // style 代码正则
                    Pattern pattern = Pattern.compile("style=\".*?\"");
                    Matcher matcher = pattern.matcher(line);
                    // 将 style="name:value;"  转为 :style="[{name:value}]"
                    resultText.append(":style=\"");
                    while (matcher.find()) {
                        String styleStr = matcher.group();
                        styleStr = styleStr.replace("style=\"", "").replace("\"", "");
                        resultText.append(parseStyleList(styleStr));
                    }
                    resultText.append("\"");
                    String[] tailArr = pattern.split(line);
                    // 行文本尾部 加入结果文本
                    if (tailArr.length != 0 && tailArr.length > 1) {
                        resultText.append(tailArr[1]);
                    }
                } else if (classMatcher.find()) { // 处理class样式
                    // 遍历查找 class 名称
                    for (String classNameLine : lineList) {
                        // 查询  .class-name #id-name 样式定义 不支持 tag-name
                        if (classNameLine.contains("{") && (classNameLine.contains(".") || classNameLine.contains("#"))) {
                            String className = classNameLine.trim().replace(".", "").replace("#", "").replace("{", "");
                            // 横线转驼峰
                            className = lineToHump(className);
                            // 如果是多重定义的class 只保留一个
                            if (className.contains(" ")) {
                                className = className.split(" ")[0];
                            }
                            // 处理样式键值对
                            String styleStr = classMatcher.group().trim().replace(";", "");
                            String[] styleArr = parseStyle(styleStr).replace(",", "").split(":");
                            // class 键值对映射
                            Map<String, String> innerClassMap = classMap.get(className);
                            if (innerClassMap == null) {
                                innerClassMap = new HashMap<>();
                            }
                            // class 键值对映射加入 class样式映射
                            innerClassMap.put(styleArr[0], styleArr[1]);
                            classMap.put(className, innerClassMap);
                            break;
                        }
                    }
                } else if (classUseMatcher.find()) {
                    String classUseStr = classUseMatcher.group();
                    String classUseHumpStr = lineToHump(classUseStr.replace("class=", "").replace("id=", "").replaceAll("\"", ""));
                    // 行文本头部加入结果文本
                    resultText.append(line, 0, line.indexOf(classUseStr));
                    resultText.append(classUseStr);
                    resultText.append(" :class=\"");
                    // class 转 v-bind:class 横线命名转驼峰
                    resultText.append(classUseHumpStr);
                    resultText.append("\"");
                    // 行文本尾部加入结果文本
                    resultText.append(line, line.indexOf(classUseStr) + classUseStr.length(), line.length());
                } else {
                    resultText.append(line);
                }
                // 每行末尾加入换行
                resultText.append("\n");
            }

//            System.out.println(classMap);
            StringBuffer dataBuffer = new StringBuffer();
            Matcher dataMatcher = Pattern.compile("data.*?\n.*?return.*?\\{", Pattern.MULTILINE).matcher(resultText);
            if (dataMatcher.find()) {
                dataMatcher.appendReplacement(dataBuffer, "data: function () {\n" +
                        "      return {\n" +
                        "        rate,\n");
                for (String key : classMap.keySet()) {
                    Map<String, String> innerClassMap = classMap.get(key);
                    dataBuffer.append("        ");
                    dataBuffer.append(key);
                    dataBuffer.append(": {");
                    for (String innerKey : innerClassMap.keySet()) {
                        dataBuffer.append(innerKey);
                        dataBuffer.append(": ");
                        dataBuffer.append(innerClassMap.get(innerKey));
                        dataBuffer.append(",");
                    }
//                    stringBuffer.append("        ");
                    dataBuffer.append("},\n");
                }
            }
            dataMatcher.appendTail(dataBuffer);
            resultText = new StringBuilder(dataBuffer);


            // 比例计算 常量
            String rateDefineStr = "\n" +
                    "  const scale = 16 / 9\n" +
                    "  const headerHeight = 47;\n" +
                    "  const tabHeight = 27;\n" +
                    "  const tabPadding = 5;\n" +
                    "  const designHeight=1080;\n" +
                    "  const marginTop = headerHeight + tabHeight + tabPadding;\n" +
                    "  const marginBottom = tabPadding;\n" +
                    "  const clientWidth = document.body.clientWidth\n" +
                    "  const windowHeight = document.body.clientHeight;\n" +
                    "  const clientHeight = windowHeight - marginTop - marginBottom;\n" +
                    "  const innerHeight = clientHeight;\n" +
                    "  const rate = innerHeight / designHeight\n" +
                    "  const centerWidth = clientHeight * scale;\n" +
                    "  const paddingWidth = (((clientWidth - 5 - 5) - (clientHeight * scale)) / 2);" +
                    "\n  ;\n";
            StringBuffer constBuffer = new StringBuffer();
            Matcher constMatcher = Pattern.compile("export default \\{", Pattern.MULTILINE).matcher(resultText);

            if (constMatcher.find()) {
                constMatcher.appendReplacement(constBuffer, rateDefineStr);
                constBuffer.append("  export default {");
                constMatcher.appendTail(constBuffer);
                System.out.println(constBuffer);
            }

            resultText = new StringBuilder(constBuffer);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            fileReader.close();
            bufferedReader.close();
        }

//        System.out.println(resultText.toString());
        FileWriter fileWriter = null;
        BufferedWriter bufferedWriter = null;
        try {
            File file = new File("screen2.vue");
            if (!file.exists()) {
                file.createNewFile();
            }
            fileWriter = new FileWriter(file);
            bufferedWriter = new BufferedWriter(fileWriter);
            bufferedWriter.write(resultText.toString());
            bufferedWriter.flush();
        } catch (Exception e) {
            System.err.println(e);
        } finally {
            bufferedWriter.close();
            fileWriter.close();
        }

    }

    /**
     * 处理样式键值对
     * 横线分隔转驼峰命名 带 px 转为 100*rate+'px' 形式
     *
     * @param style 样式键值对字符串  class-name:value
     * @return 处理后的字符串 className:'value',
     */
    public static String parseStyle(String style) {
        StringBuilder stringBuilder = new StringBuilder();
        String[] stringArr = StringUtils.split(style, ":");
        String name = stringArr[0];
        String value = stringArr[1];
        stringBuilder.append(lineToHump(name));
        stringBuilder.append(":");
        if (value.contains("px")) {
            value = value.trim().replace("px", "");
            Integer intValue;
            try {
                intValue = Integer.valueOf(value);
                stringBuilder.append(intValue);
                stringBuilder.append("*rate");
                stringBuilder.append("+'px'");
            } catch (Exception e) {
                stringBuilder.append("'");
                stringBuilder.append(value);
                stringBuilder.append("'");
            }
        } else {
            stringBuilder.append("'");
            stringBuilder.append(value);
            stringBuilder.append("'");
        }
        stringBuilder.append(",");
        return stringBuilder.toString();
    }

    /**
     * 处理样式列表
     *
     * @param styleStr 样式文本
     * @return 处理后的字符串
     */
    public static String parseStyleList(String styleStr) {
        StringBuilder stringBuilder = new StringBuilder();
        String[] styles = styleStr.split(";");
        stringBuilder.append("[{");
        for (String style : styles) {
            stringBuilder.append(parseStyle(style));
        }
        stringBuilder.append("}]");
        return stringBuilder.toString();
    }
}
